using Microsoft.Extensions.Logging;
using System.Text.Json;
using ConsoleApi.Models;
using ConsoleApi.Services.Interfaces;

namespace ConsoleApi.Services;

/// <summary>
/// 天气预警规则引擎
/// </summary>

public class WeatherAlertRuleEngine : IWeatherAlertRuleEngine
{
    private readonly ILogger<WeatherAlertRuleEngine> _logger;
    private readonly IRealWeatherService _weatherService;

    public WeatherAlertRuleEngine(ILogger<WeatherAlertRuleEngine> logger, IRealWeatherService weatherService)
    {
        _logger = logger;
        _weatherService = weatherService;
    }

    public async Task<List<ProductionAlert>> AnalyzeWeatherImpactAsync(WeatherData weatherData, List<ProductionActivity> activities)
    {
        var alerts = new List<ProductionAlert>();
        
        foreach (var activity in activities)
        {
            var impact = await AnalyzeSingleActivityAsync(weatherData, activity);
            if (impact.Severity != AlertSeverity.None)
            {
                alerts.Add(new ProductionAlert
                {
                    Id = Guid.NewGuid().ToString(),
                    ActivityId = activity.Id,
                    ActivityName = activity.Name,
                    WeatherCondition = weatherData.Current?.Text ?? "未知",
                    Temperature = weatherData.Current?.Temp ?? 0,
                    Severity = impact.Severity,
                    Impact = impact.Description,
                    Recommendations = impact.Recommendations,
                    CreatedAt = DateTime.Now,
                    Status = AlertStatus.Active
                });
            }
        }
        
        return alerts;
    }

    public async Task<List<ProductionAlert>> GenerateAlertsAsync(string city, string activityType)
    {
        var weatherData = await _weatherService.GetWeatherByCityAsync(city);
        var activities = GetProductionActivities(activityType);
        
        return await AnalyzeWeatherImpactAsync(weatherData, activities);
    }

    public async Task<WeatherImpactAnalysis> AnalyzeProductionImpactAsync(string city, string activityType)
    {
        var weatherData = await _weatherService.GetWeatherByCityAsync(city);
        var activities = GetProductionActivities(activityType);
        
        var analysis = new WeatherImpactAnalysis
        {
            City = city,
            ActivityType = activityType,
            CurrentWeather = weatherData.Current,
            Forecast = weatherData.Forecast?.Take(3).ToList(),
            Alerts = await AnalyzeWeatherImpactAsync(weatherData, activities),
            RiskLevel = CalculateRiskLevel(weatherData, activities),
            Recommendations = GenerateRecommendations(weatherData, activities),
            AnalysisTime = DateTime.Now
        };
        
        return analysis;
    }

    public async Task<List<WeatherTrend>> GetWeatherTrendsAsync(string city)
    {
        var weatherData = await _weatherService.GetWeatherByCityAsync(city);
        var trends = new List<WeatherTrend>();
        
        if (weatherData.Forecast != null)
        {
            for (int i = 0; i < weatherData.Forecast.Count - 1; i++)
            {
                var current = weatherData.Forecast[i];
                var next = weatherData.Forecast[i + 1];
                
                trends.Add(new WeatherTrend
                {
                    Date = current.Date,
                    TemperatureChange = next.MaxTemp - current.MaxTemp,
                    Trend = current.Text != next.Text ? "天气变化" : "天气稳定"
                });
            }
        }
        
        return trends;
    }

    public async Task<ProductionRecommendation> GetProductionRecommendationsAsync(string city, string activityType)
    {
        var weatherData = await _weatherService.GetWeatherByCityAsync(city);
        var activities = GetProductionActivities(activityType);
        
        return new ProductionRecommendation
        {
            ActivityType = activityType,
            Recommendations = GenerateRecommendations(weatherData, activities),
            RiskLevel = CalculateRiskLevel(weatherData, activities),
            GeneratedAt = DateTime.Now
        };
    }

    private async Task<WeatherImpact> AnalyzeSingleActivityAsync(WeatherData weatherData, ProductionActivity activity)
    {
        var impact = new WeatherImpact();
        
        // 温度影响分析
        if (weatherData.Current != null)
        {
            var temp = weatherData.Current.Temp;
            
            if (temp > 35)
            {
                impact.Severity = AlertSeverity.High;
                impact.Description = "高温预警：温度超过35°C，严重影响户外作业";
                impact.Recommendations.Add("暂停户外作业");
                impact.Recommendations.Add("增加休息频率");
                impact.Recommendations.Add("加强防暑降温措施");
            }
            else if (temp > 30)
            {
                impact.Severity = AlertSeverity.Medium;
                impact.Description = "温度较高：建议调整作业时间";
                impact.Recommendations.Add("避开正午高温时段");
                impact.Recommendations.Add("增加休息时间");
            }
            else if (temp < 5)
            {
                impact.Severity = AlertSeverity.High;
                impact.Description = "低温预警：温度低于5°C，注意防寒保暖";
                impact.Recommendations.Add("加强保暖措施");
                impact.Recommendations.Add("注意设备防冻");
            }
        }
        
        // 天气状况影响分析
        if (weatherData.Current != null)
        {
            var weather = weatherData.Current.Text;
            
            if (weather.Contains("雨") || weather.Contains("雪"))
            {
                impact.Severity = GetMaxSeverity(impact.Severity, AlertSeverity.High);
                impact.Description += "\n恶劣天气：影响户外作业和物流运输";
                impact.Recommendations.Add("暂停户外作业");
                impact.Recommendations.Add("加强货物防护");
                impact.Recommendations.Add("注意交通安全");
            }
            else if (weather.Contains("雾") || weather.Contains("霾"))
            {
                impact.Severity = GetMaxSeverity(impact.Severity, AlertSeverity.Medium);
                impact.Description += "\n能见度低：影响运输和户外作业";
                impact.Recommendations.Add("降低作业速度");
                impact.Recommendations.Add("加强安全措施");
            }
        }
        
        return impact;
    }

    private List<ProductionActivity> GetProductionActivities(string activityType)
    {
        return activityType switch
        {
            "户外作业" => new List<ProductionActivity>
            {
                new() { Id = "1", Name = "建筑施工作业", Type = "户外", IsOutdoor = true },
                new() { Id = "2", Name = "设备安装调试", Type = "户外", IsOutdoor = true },
                new() { Id = "3", Name = "现场巡检", Type = "户外", IsOutdoor = true }
            },
            "物流运输" => new List<ProductionActivity>
            {
                new() { Id = "4", Name = "货物运输", Type = "物流", IsOutdoor = false },
                new() { Id = "5", Name = "仓储作业", Type = "物流", IsOutdoor = false }
            },
            "设备维护" => new List<ProductionActivity>
            {
                new() { Id = "6", Name = "设备检修", Type = "维护", IsOutdoor = false },
                new() { Id = "7", Name = "预防性维护", Type = "维护", IsOutdoor = false }
            },
            _ => new List<ProductionActivity>
            {
                new() { Id = "8", Name = "通用生产活动", Type = "通用", IsOutdoor = false }
            }
        };
    }

    private RiskLevel CalculateRiskLevel(WeatherData weatherData, List<ProductionActivity> activities)
    {
        var maxRisk = RiskLevel.Low;
        
        if (weatherData.Current != null)
        {
            var temp = weatherData.Current.Temp;
            var weather = weatherData.Current.Text;
            
            if (temp > 35 || temp < 5 || weather.Contains("雨") || weather.Contains("雪"))
            {
                maxRisk = RiskLevel.High;
            }
            else if (temp > 30 || weather.Contains("雾"))
            {
                maxRisk = RiskLevel.Medium;
            }
        }
        
        return maxRisk;
    }

    private List<string> GenerateRecommendations(WeatherData weatherData, List<ProductionActivity> activities)
    {
        var recommendations = new List<string>();
        
        if (weatherData.Current != null)
        {
            var temp = weatherData.Current.Temp;
            var weather = weatherData.Current.Text;
            
            if (temp > 35)
            {
                recommendations.Add("高温天气，建议暂停户外作业");
                recommendations.Add("调整工作时间至早晚凉爽时段");
                recommendations.Add("增加员工休息频率，注意防暑");
            }
            else if (temp < 5)
            {
                recommendations.Add("低温天气，注意防寒保暖");
                recommendations.Add("检查设备防冻措施");
                recommendations.Add("加强安全防护");
            }
            
            if (weather.Contains("雨") || weather.Contains("雪"))
            {
                recommendations.Add("恶劣天气，暂停户外高风险作业");
                recommendations.Add("加强货物防护和运输安全");
                recommendations.Add("准备应急响应预案");
            }
        }
        
        return recommendations;
    }

    private string GetCurrentRecommendation(WeatherData weatherData, List<ProductionActivity> activities)
    {
        if (weatherData.Current == null) return "无法获取天气信息";
        
        var temp = weatherData.Current.Temp;
        var weather = weatherData.Current.Text;
        
        if (temp > 35)
            return "高温天气，建议暂停户外作业，调整生产计划";
        else if (temp < 5)
            return "低温天气，注意防寒保暖，检查设备状态";
        else if (weather.Contains("雨") || weather.Contains("雪"))
            return "恶劣天气，暂停户外作业，加强安全防护";
        else
            return "天气适宜，可正常进行生产活动";
    }

    private List<ScheduleAdjustment> GetScheduleAdjustments(WeatherData weatherData, List<ProductionActivity> activities)
    {
        var adjustments = new List<ScheduleAdjustment>();
        
        if (weatherData.Current != null)
        {
            var temp = weatherData.Current.Temp;
            
            if (temp > 35)
            {
                adjustments.Add(new ScheduleAdjustment
                {
                    Type = "时间调整",
                    Description = "避开正午高温时段",
                    Priority = Priority.High
                });
            }
            else if (temp < 5)
            {
                adjustments.Add(new ScheduleAdjustment
                {
                    Type = "时间调整",
                    Description = "选择温度相对较高的时段",
                    Priority = Priority.Medium
                });
            }
        }
        
        return adjustments;
    }

    private List<string> GetSafetyMeasures(WeatherData weatherData, List<ProductionActivity> activities)
    {
        var measures = new List<string>();
        
        if (weatherData.Current != null)
        {
            var temp = weatherData.Current.Temp;
            var weather = weatherData.Current.Text;
            
            if (temp > 35)
            {
                measures.Add("配备防暑降温设备");
                measures.Add("增加安全巡检频率");
                measures.Add("准备应急医疗用品");
            }
            else if (temp < 5)
            {
                measures.Add("加强保暖防护装备");
                measures.Add("检查设备防冻状态");
                measures.Add("增加安全警示标识");
            }
            
            if (weather.Contains("雨") || weather.Contains("雪"))
            {
                measures.Add("加强防滑防摔措施");
                measures.Add("准备应急照明设备");
                measures.Add("增加安全警示标识");
            }
        }
        
        return measures;
    }

    private List<string> GetEquipmentRecommendations(WeatherData weatherData, List<ProductionActivity> activities)
    {
        var recommendations = new List<string>();
        
        if (weatherData.Current != null)
        {
            var temp = weatherData.Current.Temp;
            var weather = weatherData.Current.Text;
            
            if (temp > 35)
            {
                recommendations.Add("检查设备散热系统");
                recommendations.Add("准备备用设备");
                recommendations.Add("加强设备监控");
            }
            else if (temp < 5)
            {
                recommendations.Add("检查设备防冻系统");
                recommendations.Add("预热关键设备");
                recommendations.Add("加强设备保温");
            }
            
            if (weather.Contains("雨") || weather.Contains("雪"))
            {
                recommendations.Add("检查设备防水性能");
                recommendations.Add("准备防雨防雪设备");
                recommendations.Add("加强设备防护");
            }
        }
        
        return recommendations;
    }

    private double CalculateRiskIncrease(ForecastDay current, ForecastDay next)
    {
        var tempRisk = Math.Abs(next.MaxTemp - current.MaxTemp) * 0.1;
        var weatherRisk = current.Text != next.Text ? 0.3 : 0.0;
        
        return tempRisk + weatherRisk;
    }

    private AlertSeverity GetMaxSeverity(AlertSeverity current, AlertSeverity newSeverity)
    {
        if (current == AlertSeverity.High || newSeverity == AlertSeverity.High)
            return AlertSeverity.High;
        if (current == AlertSeverity.Medium || newSeverity == AlertSeverity.Medium)
            return AlertSeverity.Medium;
        return AlertSeverity.Low;
    }
} 